/**
 * Created by hjqi on 2016/2/11.
 */

var http = require('http'),
    https = require('https'),
    URL = require('url'),
    qs = require('querystring'),
    logger = require('../log4js/log4js').logger('httpRequest.js');

exports.httpRequest = function (customHeaders){
    this._customHeaders = customHeaders || {};
}

exports.httpRequest.prototype._chooseHttpLibrary= function( parsedUrl ) {
    var http_library= https;
    if( parsedUrl.protocol != "https:" ) {
        http_library= http;
    }
    return http_library;
};

exports.httpRequest.prototype._request = function(url,method,headers,post_body,callback){

    var parsedUrl= URL.parse( url, true );
    if( parsedUrl.protocol == "https:" && !parsedUrl.port ) {
        parsedUrl.port= 443;
    }

    var http_library= this._chooseHttpLibrary( parsedUrl );

    var realHeaders= {};
    for( var key in this._customHeaders ) {
        realHeaders[key]= this._customHeaders[key];
    }
    if( headers ) {
        for(var key in headers) {
            realHeaders[key] = headers[key];
        }
    }
    realHeaders['Host']= parsedUrl.host;
    if( realHeaders["Authorization"] ){
        //noop
    }else if (!realHeaders['User-Agent']) {
        realHeaders['User-Agent'] = 'Node-oauth';
    }

    if( post_body ) {
        if ( Buffer.isBuffer(post_body) ) {
            realHeaders["Content-Length"]= post_body.length;
        } else {
            realHeaders["Content-Length"]= Buffer.byteLength(post_body);
        }
    } else {
        realHeaders["Content-length"]= 0;
    }

    /*if( access_token && !('Authorization' in realHeaders)) {
        if( ! parsedUrl.query ) parsedUrl.query= {};
        parsedUrl.query[this._accessTokenName]= access_token;
    }*/

    var queryStr= qs.stringify(parsedUrl.query);
    if( queryStr ) queryStr=  "?" + queryStr;
    var options = {
        host:parsedUrl.hostname,
        port: parsedUrl.port,
        path: parsedUrl.pathname + queryStr,
        method: method,
        headers: realHeaders
    };

    this._executeRequest( http_library, options, post_body, callback );

}

exports.httpRequest.prototype._executeRequest= function( http_library, options, post_body, callback ) {


    var callbackCalled= false;
    function passBackControl( response, result ) {
        if(!callbackCalled) {
            callbackCalled=true;
            if( (response.statusCode >= 200 && response.statusCode <= 299) && (response.statusCode != 301) && (response.statusCode != 302) ) {
                callback({ statusCode: response.statusCode, data: result }, result, response);
            } else {
                callback(null, result, response);
            }
        }
    }
    if( http_library == https ){
        process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0"; //跳过自生成证书认证，由于docker_auth支持的是https方式，此处跳过CA证书验证
        //埋个坑，避免以后因为有了商用CA而失效
        logger.warn("Skip TLS authentication ,set NODE_TLS_REJECT_UNAUTHORIZED=0,if you have any authenticate problem,maybe you can change here!") ;
    }
    var result= "";
    var request = http_library.request(options);
    request.on('response', function (response) {
        response.on("data", function (chunk) {
            result+= chunk
        });
        response.addListener("end", function () {
            if(response && response["statusCode"] !=200 ){
                logger.info("Response.statusCode isn't 200,but "+response["statusCode"]+","+response["statusMessage"] ) ;
            }
            passBackControl( response, result );
        });
    });
    request.on('error', function(e) {
        callbackCalled= true;
        callback(e);
    });

    if( (options.method == 'POST' || options.method == 'PUT' || options.method == 'PATCH' || options.method == 'DELETE') && post_body ) {
        request.write(post_body);
    }
    request.end();
}
